// 解析 time 发送的二进制时间。
#include <muduo/base/Logging.h>
#include <muduo/net/Endian.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/InetAddress.h>
#include <muduo/net/TcpClient.h>
#include <boost/bind.hpp>
#include <stdio.h>

using namespace muduo;
using namespace muduo::net;

class TimeClient : boost::noncopyable {
public:
	TimeClient(EventLoop *loop, const InetAddress &serverAddr)
		: loop_(loop), client_(loop, serverAddr, "TimeClient") {
		client_.setConnectionCallback(boost::bind(&TimeClient::OnConnection, this, _1));
		client_.setMessageCallback(boost::bind(&TimeClient::OnMessage, this, _1, _2, _3));
	}

	void Connect() {
		client_.connect();
	}

private:
	void OnConnection(const TcpConnectionPtr &conn) {
		LOG_INFO << conn->localAddress().toIpPort() << " -> "
		         << conn->peerAddress().toIpPort() << " is "
		         << (conn->connected() ? "UP" : "DOWN");
		if (!conn->connected())
			loop_->quit();
	}

	void OnMessage(const TcpConnectionPtr &conn, Buffer *buf, Timestamp receiveTime) {
		if (buf->readableBytes() >= sizeof(int32_t)) {
			const void *data = buf->peek();
			int32_t be32 = *static_cast<const int32_t*>(data);
			buf->retrieve(sizeof(int32_t));
			time_t time = sockets::networkToHost32(be32);
			Timestamp ts(implicit_cast<uint64_t>(time) * Timestamp::kMicroSecondsPerSecond);
			LOG_INFO << "Server time = " << time << ", " << ts.toFormattedString();
		} else {
			LOG_INFO << conn->name() << " no enought data " << buf->readableBytes()
			         << " at " << receiveTime.toFormattedString();
		}
	}

	EventLoop *loop_;
	TcpClient client_;
};

int
main(int argc, char **argv) {
	LOG_INFO << "pid = " << getpid();
	if (argc > 1) {
		EventLoop loop;
		InetAddress serverAddr(argv[1], 2037);
		TimeClient timeClient(&loop, serverAddr);
		timeClient.Connect();
		loop.loop();
	} else {
		printf("Usage: %s host_ip\n", argv[0]);
	}
}
